package com.wenx.remotestrategy;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;

import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.*;
import java.util.stream.Collectors;

/**
 * 访问服务
 */
public class AccessService {

    private RemoteInterface remoteInterface;

    public AccessService() {
        this.remoteInterface = new RemoteService();
    }


    public Object getRemoteResult(String id) {
        Object remoteResult = remoteInterface.getRemoteResult(id);
        return remoteResult;
    }


    private BlockingDeque<Map<String,Object>> deque = new LinkedBlockingDeque<>();


    public Object getRemoteResultParallel(String id) {
        String xid = UUID.randomUUID().toString();
        CompletableFuture<Object> future = new CompletableFuture<>();

        ImmutableMap<String, Object> map = ImmutableMap.<String, Object>builder()
                .put("xid", xid)
                .put("future", future)
                .put("id", id)
                .build();
        deque.add(map);
        return future.join();
    }


    //项目初始化时运行
    public void accessRemoteServices() {
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
        scheduledExecutorService.scheduleAtFixedRate(() ->{
            //从延迟队列中获取要访问的id
            if (deque.size() == 0) {
                //空队列，不处理
                return;
            }
            //获取队列中的数据
            List<Map<String,Object>> mapList = Lists.newArrayList();
            while (deque.size() > 0) {
                //队列数据出栈
                Map<String, Object> poll = deque.poll();
                mapList.add(poll);
            }
            //获取请求id集合
            List<String> ids = mapList.stream()
                    .map(map -> (String)map.get("id"))
                    .collect(Collectors.toList());
            //访问远程批量接口
            List<String> results = remoteInterface.getResults(ids);

            //通过results中的id和mapList中的id想匹配，得到 future --> results 然后
            mapList.forEach(map -> {
                String id = (String)map.get("id");
                String s = results.stream().filter(id::equals).findFirst().get();
                CompletableFuture<Object> future = (CompletableFuture)map.get("future");
                //为每个请求线程分配结果
                future.complete(s);
            });

        },0L,10L,TimeUnit.MILLISECONDS);
    }


}
